package cn.e4j.core.quartz.job;

import cn.digiwin.wx.utils.WeixinHandler;
import cn.e4j.core.dto.impl.Dto;
import cn.e4j.core.quartz.AppJob;
import cn.e4j.core.util.DateUtils;
import cn.e4j.core.util.SpringContextHolder;
import cn.e4j.core.util.ToolUtil;
import cn.e4j.modular.job.service.impl.CalendarJobServiceImpl;
import cn.e4j.modular.system.entity.SysTask;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;

/**
 * 日历事件提醒任务
 * Created by wenchuan.li on 2019-12-02.
 */
@Component("CalendarJob")
@DisallowConcurrentExecution
@Slf4j
public class CalendarJob extends AppJob {

    public String getDescribe() {
        return "日历事件提醒任务";
    }
    public String getDescribeOra() {
        return "日历事件提醒任务";
    }

    private static DateTimeFormatter d1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

    @Override
    public void logic(JobExecutionContext context, SysTask sysTask, Map<String, String> inDto) {

        long count = 0;
        long allowLoop = 0;
        long maxSize = 100;
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDate localDate = LocalDate.now();
        Dto queryDto = new Dto();

        try {

            CalendarJobServiceImpl calendarJobServiceImpl = SpringContextHolder.getBean("calendarJobServiceImpl");
            queryDto.put("GWBADOCDATE", DateUtils.getDate("yyyy-MM-dd"));

            // 最多取10次
            do {
                allowLoop++;

                // 每次取 100条数据
                Page<Object> page = new Page<>(allowLoop, maxSize);
                List<Dto> task = calendarJobServiceImpl.getlistPage(page, queryDto);
                count = page.getTotal();

                for (int i = 0, j = task.size(); i < j; i++) {
                    Dto item = task.get(i);

                    // 重复类型
                    String GWBA009 = item.getString("GWBA009");
                    // 已经执行提醒次数
                    long GWBA023 = item.getLong("GWBA023");
                    // 最后一次提醒时间
                    LocalDateTime GWBA024 = item.getLocalDateTime("GWBA024");

                    long beforeMinutes = remindMinutes(item.getString("GWBA012"));
                    LocalDateTime startDateTime = LocalDateTime.parse(item.getString("GWBA003"), d1);
                    LocalDateTime endDateTime = LocalDateTime.parse(item.getString("GWBA004"), d1);

                    // 当前时间与开始时间 分钟差
                    long betweenStart = ChronoUnit.MINUTES.between(localDateTime, startDateTime);

                    // 重复执行时间距离当前时间 还有多少分钟
                    long betweenRepeat = repeatMinutes(GWBA009, startDateTime, GWBA024);

                    // 提前多少分钟提醒
                    long _remindMinutes = remindMinutes(GWBA009);

                    if ((betweenStart < _remindMinutes && GWBA023 == 0) // 未提醒过
                            || (!"0".equals(GWBA009) && betweenRepeat < _remindMinutes)
                    ) {

                        // 发送消息
                        sendMsg(item);

                        //修改日历信息
                        item.put("GWBA024", LocalDateTime.now());
                        calendarJobServiceImpl.updateGwba(item);
                    }
                }

            } while (count >= maxSize && allowLoop < 10);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // 获取提前多少分钟提醒
    private long remindMinutes(String type) {
        long minutes = 5;
        switch (type) {
            case "3":
                minutes = 10;
                break;
            case "4":
                minutes = 15;
                break;
            case "5":
                minutes = 30;
                break;
            case "6":
                minutes = 60;
                break;
            case "7":
                minutes = 120;
                break;
            case "8":
                minutes = 60 * 24;
                break;
            case "9":
                minutes = 60 * 24 * 2;
                break;
            case "10":
                minutes = 60 * 24 * 7;
                break;
        }
        return minutes;
    }

    // 获取重复执行 周期 --分钟
    //  <option value="0">永不</option>
    //  <option value="1">每天</option>
    //  <option value="2">每周</option>
    //  <option value="3">每两周</option>
    //  <option value="4">每月</option>
    private long repeatMinutes(String type, LocalDateTime start, LocalDateTime last) {
        long minutes = 0;
        if ("0".equals(type)) {
            return minutes;
        }

        LocalDateTime localDateTime = LocalDateTime.now();

        if (ToolUtil.isEmpty(last)) {
            last = start;
        }

        LocalDateTime dt;

        switch (type) {
            case "1":
                // 上一次执行时间
                dt = LocalDateTime.of(last.getYear(),
                        last.getMonth(),
                        last.getDayOfMonth(),
                        start.getHour(),
                        start.getMinute(),
                        00);
                dt = dt.plusDays(1); // +1天
                minutes = ChronoUnit.MINUTES.between(localDateTime, dt);
                break;
            case "2":
                // 上一次执行时间
                dt = LocalDateTime.of(last.getYear(),
                        last.getMonth(),
                        last.getDayOfMonth(),
                        start.getHour(),
                        start.getMinute(),
                        00);
                dt = dt.plusDays(7); // +7天
                minutes = ChronoUnit.MINUTES.between(localDateTime, dt);
                break;
            case "3":
                // 上一次执行时间
                dt = LocalDateTime.of(last.getYear(),
                        last.getMonth(),
                        last.getDayOfMonth(),
                        start.getHour(),
                        start.getMinute(),
                        00);
                dt = dt.plusDays(14); // +14天
                minutes = ChronoUnit.MINUTES.between(localDateTime, dt);
                break;
            case "4":

                dt = LocalDateTime.of(last.getYear(),
                        last.getMonth(),
                        last.getDayOfMonth(),
                        start.getHour(),
                        start.getMinute(),
                        00);

                dt = dt.plusMonths(1);

                minutes = ChronoUnit.MINUTES.between(localDateTime, dt);
                break;
        }
        return minutes;
    }

    // 发送消息
    private void sendMsg(Dto item) {
        //通知
        WeixinHandler.sendMsg(item, "CRM工作日历提醒\n" +
                item.getString("GWBA001") + ": " +
                item.getString("GWBA006"));
    }

}
